package com.wantupai.translate.utils;

import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.wantupai.translate.App;
import com.wantupai.translate.bean.DataBean;

import org.json.JSONObject;
import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;

import java.io.File;
import java.lang.reflect.Type;
import java.net.SocketTimeoutException;
import java.util.List;
import java.util.Map;

import static com.wantupai.translate.utils.CommonUtils.getVersionName;

/**
 * @author luxuchang
 * @date 2019/4/24 0024
 * @description
 */
public class NetUtils {

    private static final Gson gson = new Gson();
    private volatile static NetUtils instance;

    /**
     * Double Check 单例模式
     */
    public static NetUtils getInstance() {
        if (instance == null) {
            synchronized (NetUtils.class) {
                if (instance == null) {
                    instance = new NetUtils();
                }
            }
        }
        return instance;
    }

    /**
     * 网络请求的接口回调监听器
     */
    public interface NetResponseListener {
        void onSuccess(DataBean result, int requestCode);

        void onFailed(int requestCode, String info);
    }

    /**
     * 文件下载的接口回调监听器
     */
    public interface NetDownLoadFileListener extends NetResponseListener {

        void onSuccess(File response, int requestCode);

        void onLoading(long total, long current, boolean isDownloading, int requestCode);
    }

    /**
     * 文件上传的接口回调监听
     */
    public interface NetUpLoadFileListener extends NetResponseListener {
        void onLoading(long current, boolean isDownloading, int requestCode);
    }

    private static <T> DataBean<T> fromJsonObject(String s, Class<T> clazz) {
        Type type = new ParameterizedTypeImpl(DataBean.class, new Class[]{clazz});
        return gson.fromJson(s, type);
    }

    private static <T> DataBean<List<T>> fromJsonArray(String reader, Class<T> clazz) {
        // 生成List<T> 中的 List<T>
        Type listType = new ParameterizedTypeImpl(List.class, new Class[]{clazz});
        // 根据List<T>生成完整的Result<List<T>>
        Type type = new ParameterizedTypeImpl(DataBean.class, new Type[]{listType});
        return gson.fromJson(reader, type);
    }

    /**
     * 文件上传
     */
    public Callback.Cancelable upLoadFile(String url, Map<String, String> maps, Map<String, File> file, final boolean isList, final Class clazz, final int requestCode, final NetUpLoadFileListener listener) {
        RequestParams params = new RequestParams(url);
        MyLog.e("ssp_url", url);
        if (maps != null && !maps.isEmpty()) {
            for (Map.Entry<String, String> entry : maps.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue());
                MyLog.e("ssp_key", entry.getKey() + " = " + entry.getValue());
            }
        }
        if (file != null && !file.isEmpty()) {
            for (Map.Entry<String, File> entry : file.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue().getAbsoluteFile());
                MyLog.e("ssp_key", entry.getKey() + " = " + entry.getValue().getAbsoluteFile());
            }
            // 有上传文件时使用multipart表单, 否则上传原始文件流.
            params.setMultipart(true);//这个是标示上传的文件内容的,
        }
        params.addHeader("api-version", "v3");
        params.addHeader("platform", "android");
        params.addHeader("version", getVersionName(App.getInstance()));
        params.addHeader("user-token", "106cecde-7d47-70af-5df6-432065d444a7-26116");

        return x.http().post(params, new Callback.ProgressCallback<String>() {

            @Override
            public void onSuccess(String result) {
                try {
                    MyLog.e("ssp_result::", result);
                    JSONObject object = new JSONObject(result);
                    String code = object.getString("code");
                    String data = object.getString("data");
                    String info = object.getString("info");
                    if (code.equals("200") && !TextUtils.isEmpty(data)) {
                        DataBean bean;
                        if (isList) {
                            bean = fromJsonArray(result, clazz);
                            listener.onSuccess(bean, requestCode);
                        } else if (clazz != null) {
                            bean = fromJsonObject(result, clazz);
                            listener.onSuccess(bean, requestCode);
                        } else {
                            listener.onSuccess(null, requestCode);
                        }
                    } else {
                        listener.onFailed(requestCode, info);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    listener.onFailed(requestCode, "数据异常");
                }
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                ex.printStackTrace();
                if (ex instanceof SocketTimeoutException) {
                    listener.onFailed(requestCode, "网络超时,请检查网络");
                } else {
                    listener.onFailed(requestCode, "接口请求失败");
                }
            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }

            @Override
            public void onWaiting() {

            }

            @Override
            public void onStarted() {

            }

            @Override
            public void onLoading(long total, long current, boolean isDownloading) {
                listener.onLoading(current, isDownloading, requestCode);
            }
        });
    }

    /**
     * 异步post请求
     */
    public Callback.Cancelable post(final String url, Map<String, String> maps, final boolean isList, final Class clazz, final int requestCode, final NetResponseListener listener) {
        RequestParams params = new RequestParams(url);
        MyLog.i("ssp_url", url);
        if (maps != null && !maps.isEmpty()) {
            for (Map.Entry<String, String> entry : maps.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue());
                MyLog.i("ssp_key", entry.getKey() + " = " + entry.getValue());
            }
        }
        params.addHeader("api-version", "v3");
        params.addHeader("platform", "android");
        params.addHeader("version", getVersionName(App.getInstance()));
        params.addHeader("user-token", "106cecde-7d47-70af-5df6-432065d444a7-26116");
        params.addHeader("api-token", "106cecde-7d47-70af-5df6-432065d444a7-26116");

        return x.http().post(params, new Callback.CommonCallback<String>() {

            @Override
            public void onSuccess(String result) {
                try {
                    MyLog.i("ssp_result", result);
                    JSONObject object = new JSONObject(result);
                    String info = object.getString("info");
                    String code = object.getString("code");
                    String data = object.getString("data");

                    if (code.equals("200")) {

                        DataBean bean;
                        if (clazz != null && !TextUtils.isEmpty(data)) {
                            if (isList) {
                                bean = fromJsonArray(result, clazz);
                            } else {
                                bean = fromJsonObject(result, clazz);
                            }
                            listener.onSuccess(bean, requestCode);
                        } else {
                            bean = new DataBean();
                            bean.setCode(code);
                            bean.setInfo(info);
                            listener.onSuccess(bean, requestCode);
                        }
                    } else {
                        listener.onFailed(Integer.parseInt(code), info);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
//                    listener.onFailed(requestCode, "数据解析异常"+url);
                }
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                ex.printStackTrace();
                if (ex instanceof SocketTimeoutException) {
                    listener.onFailed(requestCode, "网络超时,请检查网络");
                } else {
                    listener.onFailed(requestCode, "接口请求失败");
                }
            }

            @Override
            public void onCancelled(CancelledException cex) {
            }

            @Override
            public void onFinished() {

            }
        });
    }

}
